package com.easyidea.its.web.action.statistics;

import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import com.easyidea.its.domain.model.system.Department;
import com.easyidea.its.domain.model.system.PassPort;
import com.easyidea.its.facade.tracklog.TrackLogMgr;
import com.easyidea.its.util.DateUtil;
import com.easyidea.its.util.ItsConstants;
import com.easyidea.its.util.excel.ExportDataUtil;
import com.easyidea.its.web.action.base.ItsBaseAction;
import com.easyidea.its.web.dto.SeesionUserDto;
import com.easyidea.its.web.dto.StatisticsDto;
import com.easyidea.its.web.dto.StatisticsExport;

public class StatisticsAction extends ItsBaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2907007047750222750L;

	private TrackLogMgr trackLogMgr;

	private Collection<Department> allDepartments;

	private Collection<PassPort> passPorts;

	private Collection<String> directions;

	private StatisticsDto statisticsDto;

	private Integer currentYear = DateUtil.getYear(new Date());
	
	private List<StatisticsExport> dataset;

	private String filename = "";

	public String getFilename() {
		return filename;
	}

	public void setFilename(String filename) {
		this.filename = filename;
	}

	public String statistics() {
		initStatisticsDto();
		this.allDepartments = trackLogMgr.getAllDepartments();
		passPorts = trackLogMgr.getAllPassPorts();
		StringWriter sw = new StringWriter();
		filename = this.generateStatisticsChart(getSession(), new PrintWriter(
				sw), statisticsDto);
		SeesionUserDto dto = (SeesionUserDto)getSession().getAttribute(ItsConstants.SESSION_KEY_USER_INFO);
		 getSession().setAttribute(dto.getUserId()+"."+ItsConstants.SESSION_KEY_STATISTICS_DTO, statisticsDto);
		return SUCCESS;
	}

	private void initStatisticsDto() {
		if (statisticsDto == null) {
			statisticsDto = new StatisticsDto();
			Date currentDate = new Date();
			statisticsDto.setHourDate(DateUtil.dateToShortStr(currentDate));
			statisticsDto.setStartHour(0);
			statisticsDto.setEndHour(DateUtil.getHour(currentDate));
			statisticsDto.setEndMonth(Integer.parseInt(DateUtil
					.getMonth(currentDate)));
			statisticsDto.setStatisticsType("hour");
		}

	}

	private String generateStatisticsChart(HttpSession session, PrintWriter pw,
			StatisticsDto statisticsDto) {
		String startDate;
		String endDate;

		if (statisticsDto.getStatisticsType().equals("hour")) {
			Date hDate = DateUtil.strToDate(statisticsDto.getHourDate());
			startDate = DateUtil.dateToLongStr(hDate, statisticsDto
					.getStartHour(), statisticsDto.getStartMinute());
			statisticsDto.setStartDate(DateUtil.strToDate(startDate,
					ItsConstants.FORMATE_STYLE_DATA_NO_SECOND));
			endDate = DateUtil.dateToLongStr(hDate, statisticsDto.getEndHour(),
					statisticsDto.getEndMinute());
			statisticsDto.setEndDate(DateUtil.strToDate(endDate,
					ItsConstants.FORMATE_STYLE_DATA_NO_SECOND));
		} else if (statisticsDto.getStatisticsType().equals("day")) {
			Date dStart = statisticsDto.getDayStartDate();
			statisticsDto.setStartDate(DateUtil.getStartTime(dStart));
			Date dEnd = statisticsDto.getDayEndDate();
			statisticsDto.setEndDate(DateUtil.getEndTime(dEnd));

		} else if (statisticsDto.getStatisticsType().equals("month")) {
			statisticsDto.setStartDate(DateUtil.getStartTime(DateUtil
					.getFirstDayOfMonth(statisticsDto.getStartYear(), String
							.valueOf(statisticsDto.getStartMonth()))));
			statisticsDto.setEndDate(DateUtil.getEndTime(DateUtil
					.getLastDayOfMonth(statisticsDto.getStartYear(), String
							.valueOf(statisticsDto.getEndMonth()))));
		}
		Collection<Object[]> objs = this.trackLogMgr
				.statisticsByCondition(statisticsDto);
		dataset = ExportDataUtil.createDataset(statisticsDto, objs);
		CategoryDataset dataset = this.createDataset(statisticsDto, objs);
		JFreeChart chart = ChartFactory.createLineChart("流量统计分析图表", "时间", "流量",
				dataset, PlotOrientation.VERTICAL, false, false, false);

		ChartRenderingInfo info = new ChartRenderingInfo(
				new StandardEntityCollection());
		CategoryPlot plot = chart.getCategoryPlot();
		// customise the range axis...
		NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
		rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		rangeAxis.setAutoRangeIncludesZero(true);
		rangeAxis.setUpperMargin(0.20);
		rangeAxis.setLabelAngle(Math.PI / 2.0);
	    CategoryAxis categoryAxis = plot.getDomainAxis(); 

	    // 横轴上的 Lable 90度倾斜 

	    categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);


		LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
				.getRenderer();
		// renderer.setBaseShape(new Rectangle2D.Double(-1.5, -1.5, 3, 3),
		// true); //设置点
		renderer.setShape(new Rectangle2D.Double(-1.5, -1.5, 3, 3));
		renderer.setShapesVisible(true);
		renderer.setSeriesPaint(3, Color.red);
		renderer.setSeriesLinesVisible(3, false);

		renderer
				.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());// 显示折点数据
		renderer.setItemLabelsVisible(true);
		// 写图表对象到outstream
		try {
			// 生成图片
			Double width = clientWidth.intValue() * 0.8;
			filename = ServletUtilities.saveChartAsPNG(chart, width.intValue(),
					400, info, session);
			ChartUtilities.writeImageMap(pw, filename, info, false);
		} catch (Exception ex) {
			log.error(ex.getStackTrace());
		}
		pw.flush();
		// 返回生成图片的文件名
		return filename;
	}

	private CategoryDataset createDataset(StatisticsDto statisticsDto,
			Collection<Object[]> objs) {

		// row keys...
		final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		final String series1 = "";
		if (statisticsDto.getStatisticsType().equals("hour")) {
			createDataSetByHour(statisticsDto, objs, dataset, series1);
		} else if (statisticsDto.getStatisticsType().equals("day")) {
			createDataSetByDay(statisticsDto, objs, dataset, series1);
		} else if (statisticsDto.getStatisticsType().equals("month")) {
			createDataSetByMonth(statisticsDto, objs, dataset, series1);
		}

		// create the dataset...

		return dataset;

	}

	private void createDataSetByMonth(StatisticsDto statisticsDto,
			Collection<Object[]> objs, final DefaultCategoryDataset dataset,
			final String series1) {
		Map<Integer, Integer> dbMap = new HashMap<Integer, Integer>();
		Iterator it = objs.iterator();
		while (it.hasNext()) {
			Object[] o = (Object[]) it.next();
			Integer key = null;
			if (o[0] != null) {
			 if((o[1]) instanceof   BigInteger)
				key =  ((BigInteger)o[1]).intValue();
			 if((o[1]) instanceof   Integer)
				 key =  (Integer)o[1];
			}
			BigInteger num = (BigInteger) o[0];
			dbMap.put(key, num.intValue());
		}
		long day = statisticsDto.getEndMonth() - statisticsDto.getStartMonth();
		for (int i = 0; i <= day; i++) {

			Integer val =  (statisticsDto.getStartMonth() + i);
			String currentMonth = String
			.valueOf(statisticsDto.getStartYear())
			+ "/" + String.valueOf(val);
			if (dbMap.get(val) != null) {
				dataset.addValue(dbMap.get(val), series1, currentMonth);
			} else {
				dataset.addValue(0, series1, currentMonth);
			}

		}
	}

	private void createDataSetByDay(StatisticsDto statisticsDto,
			Collection<Object[]> objs, final DefaultCategoryDataset dataset,
			final String series1) {
		Date dStart = statisticsDto.getDayStartDate();
		Date dEnd = statisticsDto.getDayEndDate();
		long day = DateUtil.getdate(dEnd, dStart);
		Map<Date, Integer> dbMap = new HashMap<Date, Integer>();
		Iterator it = objs.iterator();
		while (it.hasNext()) {
			Object[] o = (Object[]) it.next();
			Date key = null;
			if (o[0] != null) {
				key = ((Date) o[1]);
			}
			BigInteger num = (BigInteger) o[0];
			dbMap.put(key, num.intValue());
		}
		for (int i = 0; i <= day; i++) {
			String today = String.valueOf(DateUtil.getYear(dStart)) + "/"
					+ String.valueOf(DateUtil.getMonth(dStart)) + "/"
					+ (String.valueOf(DateUtil.getDay(dStart) + i));
			if (dbMap.get(DateUtil.addDate(dStart, i)) != null) {

				dataset.addValue(dbMap.get(DateUtil.addDate(dStart, i)),
						series1, today);
			} else {
				dataset.addValue(0, series1, today);
			}
		}
	}

	private void createDataSetByHour(StatisticsDto statisticsDto,
			Collection<Object[]> objs, final DefaultCategoryDataset dataset,
			final String series1) {
		Map<Integer, Integer> dbMap = new HashMap<Integer, Integer>();
		Iterator it = objs.iterator();
		while (it.hasNext()) {
			Object[] o = (Object[]) it.next();
			Integer key = null;
			if (o[0] != null) {
			 if((o[1]) instanceof   BigInteger)
				key =  ((BigInteger)o[1]).intValue();
			 if((o[1]) instanceof   Integer)
				 key =  (Integer)o[1];
			}
			BigInteger num = (BigInteger) o[0];
			dbMap.put(key.intValue(), num.intValue());
		}
		for (int i = 0; i <= statisticsDto.getEndHour()
				- statisticsDto.getStartHour(); i++) {
			Integer val = statisticsDto.getStartHour() + i;
			if (dbMap.get(val) != null) {
				dataset.addValue(dbMap.get(val), series1, String
						.valueOf(val)
						+ "时");
			} else {
				dataset.addValue(0, series1, String.valueOf(val) + "时");
			}

		}
	}


	public Collection<Department> getAllDepartments() {
		return allDepartments;
	}

	public void setAllDepartments(Collection<Department> allDepartments) {
		this.allDepartments = allDepartments;
	}

	public Collection<PassPort> getPassPorts() {
		return passPorts;
	}

	public void setPassPorts(Collection<PassPort> passPorts) {
		this.passPorts = passPorts;
	}

	public Collection<String> getDirections() {
		return directions;
	}

	public void setDirections(Collection<String> directions) {
		this.directions = directions;
	}

	public StatisticsDto getStatisticsDto() {
		return statisticsDto;
	}

	public void setStatisticsDto(StatisticsDto statisticsDto) {
		this.statisticsDto = statisticsDto;
	}

	public static long getSerialversionuid() {
		return serialVersionUID;
	}

	public TrackLogMgr getTrackLogMgr() {
		return trackLogMgr;
	}

	public void setTrackLogMgr(TrackLogMgr trackLogMgr) {
		this.trackLogMgr = trackLogMgr;
	}

	public Integer getCurrentYear() {
		return currentYear;
	}

	public void setCurrentYear(Integer currentYear) {
		this.currentYear = currentYear;
	}

	public List<StatisticsExport> getDataset() {
		return dataset;
	}

	public void setDataset(List<StatisticsExport> dataset) {
		this.dataset = dataset;
	}

}
